using System.IO;

namespace BLGenerator.BusinessLogic.FileGenerators
{
    public sealed class EntityCollectionFileGenerator
    {
        public static void Generate(Entity entity, string filename)
        {
            StreamWriter stream = new FileInfo(filename).CreateText();
            CompositeFileBlock fileBlock = new CompositeFileBlock();
            fileBlock.Add("using System.Collections.Generic;");
            fileBlock.Add("using System.Data.SqlClient;");
            fileBlock.Add(string.Format("using {0};", entity.Project.Namespace));
            fileBlock.Add(string.Format("using {0}.Entities;", entity.Project.Namespace));
            fileBlock.Add();
            fileBlock.Add(string.Format("namespace {0}.Collections", entity.Project.Namespace));
            fileBlock.Add("{");
            fileBlock.Add(FileBlock_Class(entity));
            fileBlock.Add("}");
            fileBlock.WriteToStream(stream);
            stream.Close();
        }

        private static CompositeFileBlock FileBlock_Class(Entity entity)
        {
            CompositeFileBlock fileBlock = new CompositeFileBlock();
            fileBlock.Add(string.Format("public class {0}Collection : List<{0}>", entity.EntityName));
            fileBlock.Add("{");
            fileBlock.Add(FileBlock_GetAllMethod(entity));
            fileBlock.Add();
            fileBlock.Add(FileBlock_FillFromReaderMethod(entity));
            fileBlock.Add("}");
            return fileBlock;
        }

        private static CompositeFileBlock FileBlock_GetAllMethod(Entity entity)
        {
            CompositeFileBlock fileBlock = new CompositeFileBlock();
            fileBlock.Add(string.Format("public  static {0}Collection GetAll()", entity.EntityName));
            fileBlock.Add("{");
            fileBlock.Add(1, string.Format("{0}Collection collection = new {0}Collection();", entity.EntityName));
            fileBlock.Add(1, "using (SqlConnection connection = DBConnection.Connection)");
            fileBlock.Add(1, "{");
            fileBlock.Add(2, "using (SqlCommand command = connection.CreateCommand())");
            fileBlock.Add(2, "{");
            fileBlock.Add(3, string.Format("command.CommandText = \"SELECT * FROM [{0}]\";", entity.TableName));
            fileBlock.Add(3, "using (SqlDataReader reader = command.ExecuteReader())");
            fileBlock.Add(3, "{");
            fileBlock.Add(4, "collection.FillFromReader(reader);");
            fileBlock.Add(4, "return collection;");
            fileBlock.Add(3, "}");
            fileBlock.Add(2, "}");
            fileBlock.Add(1, "}");
            fileBlock.Add("}");
            return fileBlock;
        }

        private static CompositeFileBlock FileBlock_FillFromReaderMethod(Entity entity)
        {
            CompositeFileBlock fileBlock = new CompositeFileBlock();

            fileBlock.Add("protected void FillFromReader(SqlDataReader reader)");
            fileBlock.Add("{");
            fileBlock.Add(1, "this.Clear();");
            fileBlock.Add(1, "while (reader.Read())");
            fileBlock.Add(2, string.Format("this.Add(new {0}(reader));", entity.EntityName));
            fileBlock.Add("}");

            return fileBlock;
        }
    }
}